home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h> /***/
- /* Machine or compiler-dependent portions of kernel - UNIX version */
- #include <signal.h>
- #include "global.h"
- #include "proc.h"
-
- #ifndef NO_INTSTK
- extern int16 Intstk[]; /* The signal stack */
- #endif
-
- /* If you don't have one of those machines you'd better look up the
- * contents of jmp_buf in setjmp.h or in your manual. If those don't
- * give you any hints you will have to write a small program to poke
- * around in a jmp_buf in order to find JB_SP
- */
-
- #ifndef JB_SP
-
- #if defined(i386)
- /* Template for some of the contents of the jmp_buf array on a Sun386i */
- #define JB_ONSSTACK 0
- #define JB_SP 2 /* Stack pointer */
- #endif
-
- #if defined(sun4) || defined(sparc)
- /* Template for some of the contents of the jmp_buf array on a Sun4. */
- #define JB_ONSSTACK 0
- #define JB_SP 2 /* Stack pointer */
- #endif
-
- #if defined(sun3) || defined(mc68020) || defined(mc68000)
- /* Template for some of the contents of the jmp_buf array on a Sun3. */
- #define JB_ONSSTACK 0
- #define JB_SP 2 /* Stack pointer */
- #endif
-
- #endif
-
- void
- kinit()
- {
- int i;
-
- /* Initialize interrupt stack for high-water-mark checking */
- #ifndef NO_INTSTK
- for(i=0;i<INTSTK_SIZE;i++)
- Intstk[i] = STACKPAT;
- #endif
- }
-
- /* ps() will show strange values for the stack usage of the main process.
- This is beacuse we do not fill the stack space of the main process
- with STACKPAT.
- */
-
- /* Print process table info
- * Since things can change while ps is running, the ready proceses are
- * displayed last. This is because an interrupt can make a process ready,
- * but a ready process won't spontaneously become unready. Therefore a
- * process that changes during ps may show up twice, but this is better
- * than not having it showing up at all.
- */
- int
- ps(argc,argv,p)
- int argc;
- char **argv;
- void *p;
- {
- register struct proc *pp;
- int i;
- jmp_buf env;
-
- #ifndef NO_INTSTK
- struct sigstack oss;
- sigstack((struct sigstack *)0,&oss);
- tprintf("Int Stack SP stksize maxstk\n");
- tprintf(" %-10lx%-10u%-10u\n",
- (int)oss.ss_sp,INTSTK_SIZE,chkintstk());
- #endif
-
- tprintf("PID SP stksize maxstk event fl in out name\n");
-
- for(pp = Susptab;pp != NULLPROC;pp = pp->next){
- if(tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %3d %3d %s\n",
- ptol(pp),
- ptol(pp->env[JB_SP]),
- pp->stksize,
- stkutil(pp),
- ptol(pp->event),
- pp->i_state ? 'I' : ' ',
- (pp->state & WAITING) ? 'W' : ' ',
- (pp->state & SUSPEND) ? 'S' : ' ',
- pp->input, pp->output,
- pp->name) == EOF)
- return 0;
- }
- for(i=0;i<PHASH;i++){
- for(pp = Waittab[i];pp != NULLPROC;pp = pp->next){
- if(tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %3d %3d %s\n",
- ptol(pp),ptol(pp->env[JB_SP]),pp->stksize,stkutil(pp),
- ptol(pp->event),
- pp->i_state ? 'I' : ' ',
- (pp->state & WAITING) ? 'W' : ' ',
- (pp->state & SUSPEND) ? 'S' : ' ',
- pp->input,pp->output,
- pp->name) == EOF)
- return 0;
- }
- }
- for(pp = Rdytab;pp != NULLPROC;pp = pp->next){
- if(tprintf("%-10lx%-10lx%-10u%-10u %c%c%c %3d %3d %s\n",
- ptol(pp),ptol(pp->env[JB_SP]),pp->stksize,stkutil(pp),
- pp->i_state ? 'I' : ' ',
- (pp->state & WAITING) ? 'W' : ' ',
- (pp->state & SUSPEND) ? 'S' : ' ',
- pp->input,pp->output,
- pp->name) == EOF)
- return 0;
- }
- setjmp(env);
- if(Curproc != NULLPROC){
- tprintf("%-10lx%-10lx%-10u%-10u %c %3d %3d %s\n",
- ptol(Curproc),ptol(env[JB_SP]),Curproc->stksize,
- stkutil(Curproc),
- Curproc->i_state ? 'I' : ' ',
- Curproc->input,Curproc->output,
- Curproc->name);
- }
- return 0;
- }
- int
- stkutil(pp)
- struct proc *pp;
- {
- unsigned i;
- register int16 *sp;
-
- if (pp->stack == NULL)return 0;
-
- i = pp->stksize;
- for(sp = pp->stack;*sp == STACKPAT && sp < pp->stack + pp->stksize;sp++)
- i--;
- return i;
- }
- /* Return number of used words in interrupt stack. Note hardwired value
- * for stack size;
- */
- chkintstk()
- {
- register int i;
- register int16 *cp;
-
- #ifndef NO_INTSTK
- for(i=INTSTK_SIZE,cp = Intstk; i != 0 && *cp == STACKPAT; cp++)i--;
- return i;
- #else
- return 0;
- #endif
- }
-
- /* Verify that stack pointer for current process is within legal limits;
- * also check that no one has dereferenced a null pointer
- */
- void
- chkstk()
- {
- int16 *sbase;
- int16 *stop;
- int16 *sp;
- jmp_buf env;
-
- /* Warning! KA9WSB
- * Some systems don't reliably tell you that they are on the signal stack.
- * Comment out this routine if that's the case. It should probably be
- * replaced anyway...
- */
- if(Curproc == NULLPROC)return;
-
- setjmp (env);
- sp = (int16 *) env[JB_SP];
- #ifdef JB_ONSSTACK
- if(env[JB_ONSSTACK]){
- /* Probably in interrupt context */
- return;
- }
- #endif
- sbase = Curproc->stack;
- if (sbase == 0)
- return;
- stop = sbase + Curproc->stksize;
- if(sp < sbase || sp >= stop){
- printf("Stack violation, process %s\n",Curproc->name);
- printf("SP = %lx, legal stack range [%lx,%lx)\n",
- ptol(sp),ptol(sbase),ptol(stop));
- fflush(stdout);
- abort();
- }
- }
- /* Machine-dependent initialization of a task */
-
- /* Each process gets a stack below the real stack in the stack area.
- This is really risky business since the kernel thinks that this area
- is unused. Be aware of that this might lead to problems. But it is
- unfortunately the only way to make this program work at the moment,
- since we are not allowed to move the stack pointer below the heap.
- */
- void
- psetup(pp,iarg,parg1,parg2,pc)
- struct proc *pp; /* Pointer to task structure */
- int iarg; /* Generic integer arg */
- void *parg1; /* Generic pointer arg #1 */
- void *parg2; /* Generic pointer arg #2 */
- void (*pc)(); /* Initial execution address */
- {
- int i, p;
- void startproc();
-
- /* Task initially runs with interrupts on */
- pp->i_state = 1;
-
- /* The main process needs special treatment. The NULL
- initial execution address indicates that this is indeed
- the main process. */
- if (pc == NULLVFP) {
- pp->stksize = 0;
- pp->stack = NULL;
- return;
- }
-
- /* Since the process has its stack in high memory we are not able
- * write in it directly. So instead of pushing the a stack frame
- * on the stack, we save the frame for later usage by startproc().
- */
-
- pp->startargs.parg2 = parg2;
- pp->startargs.parg1 = parg1;
- pp->startargs.iarg = iarg;
- pp->startargs.func = pc;
-
- /***** HACK we free the stack allocated by kernel.c and get us a new one
- * that is probably larger and better aligned :-)
- * When we allocate the stack, we have to leave some room at the
- * top, because the setjmp function return will presume that it
- * has a stack frame in which to scribble... so reserve about
- * 256 bytes (64 ints) for the stack... While we're at it, we
- * might as well guarantee proper stack alignment. Align it on
- * a double-word boundary, which should be the worst case for
- * most known processors.
- *
- * What's in the stack frame is important for some processors
- * (notably the SPARC!). So, before we do the assignment of
- * the new stack pointer, we copy the previous stack frame over.
- * With some assembly we can find the size of the stack frame,
- * but it's easier just to copy the entire 256 bytes. NOTE:
- * IF YOU ADD A LOT OF STUFF TO THIS ROUTINE, THE FRAME MAY
- * GROW BEYOND THE LIMIT!
- *
- * Note that this will disturb dbx or anything else that tries
- * to walk stacks backwards. It may find a partial stack frame
- * and crash...
- *
- *******/
-
- free(pp->stack);
- pp->stksize = PROCSTK_SIZE; /* in small ints */
- pp->stack = (int16 *)malloc(pp->stksize * sizeof(int16));
- for(i=0; i<pp->stksize; i++) pp->stack[i] = STACKPAT;
-
- i = setjmp(pp->env);
- if(i){
- startproc();
- } else {
- /* Compute the new stack top */
- p = (int)pp->stack;
- p = p + (pp->stksize * sizeof(int16)); /* top of stack */
- p = p - 256; /* fake current stack frame */
- p = (p & 0xfffffff8); /* fix alignment */
- /* Copy the frame (or most of it, anyway) */
- memcpy((char *)p, (char *)(pp->env[JB_SP]), 256);
- /* And set the new stack pointer. */
- pp->env[JB_SP] = p;
- }
- }
- /* The process is born and killed here */
- void
- startproc()
- {
- (*Curproc->startargs.func)(Curproc->startargs.iarg,
- Curproc->startargs.parg1,
- Curproc->startargs.parg2);
- killself();
- }
-
- unsigned
- phash(event)
- void *event;
- {
- register unsigned x;
-
- x = (unsigned) event;
-
- /* If PHASH is a power of two, this will simply mask off the
- * higher order bits
- */
- return x % PHASH;
- }
-